package com.ljk.controller.study;

import com.ljk.service.ExampleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

/**
 * 控制层(controller层)
 * <p>
 * {@link Controller}(通常作用在控制层（如 Struts2 的 Action），用于将控制层的类标识为 Spring 中的 Bean，其功能与 @Component 相同。)
 * <p>
 * {@link Component} 可以使用此注解描述 Spring 中的 Bean，但它是一个泛化的概念，仅仅表示一个组件（Bean），并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
 * <p>
 *
 * @author leng
 * @date 2020/6/19 0:30
 */
@Controller
public class ExampleController {

    private ExampleService exampleService;

    /**
     * Service官方推荐注入方式,也可直接注入到属性上(可以用但不推荐)
     * 原因如下:
     * Spring会将我们用 @Autowired 注解标识过的属性/成员变量的【访问控制检查】关闭掉，即对每个属性进行了【setAccessible(true)】的设置，导致这些属性即使我们设定了【private】权限，
     * Spring却仍然能够不通过 getter 和 setter 方法来访问这些属性，达到一定的目的。
     *
     * 造成的后果是:当将 @Autowired 注解直接写在成员变量上时，即使设定该成员变量的访问权限为private，那么也会自动将其改变成public；
     * 而将 @Autowired 注解写在成员变量的 setter 方法上则不会出现此问题。所以不建议使用前者！！！
     * 当然也可以直接将@Autowired直接写在有参构造方法上
     * <p>
     * {@link Autowired} (用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注，配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。)
     * <p>
     * {@link Qualifier} Autowired 也可以采用按 Bean 的实例名称装配的方法,只需要在上面再加一个 @Qualifier注解指定名字就可以(不常用)
     * <p>
     */
    @Autowired
    public void setExampleService(ExampleService exampleService) {
        this.exampleService = exampleService;
    }

    /**
     * 调用service方法
     */
    public void add() {
        System.out.println("示例方法,controller层的方法add被执行了");
        exampleService.add();
    }

    /**
     * 测试aop的异常
     *
     * @throws Exception
     */
    public void err() throws Exception {
        throw new Exception("异常测试");
    }

    /**<p>
     * {@link Transactional} 定义事务并且在发生符合条件时回滚,写法看  TransactionalDoc
     * 测试Mybatis
     */
    @Transactional(rollbackFor = Exception.class)
    public void myBatisTest(){
        int i = exampleService.myBatisTest();
        System.out.println(i);
    }




}
